package com.goldsprite.gameframeworks.ecs.component;

import com.goldsprite.gameframeworks.ecs.entity.GObject;
import com.goldsprite.gameframeworks.log.Debug;
import com.goldsprite.gameframeworks.utils.math.Vector2;

import java.util.*;

public class RigidbodyComponent extends Component {
	private final List<ColliderComponent> attachedColliders = new ArrayList<>();

	private BodyType bodyType = BodyType.DYNAMIC;
	public float gravityScale = 1.0f;
	private Vector2 lastPosition = new Vector2();
	public Vector2 position = new Vector2();
	private final Vector2 velocity = new Vector2();

	@Override
	public void awake() {
		super.awake();
		lastPosition.set(position.set(fields.transform.position));
	}

	// Getter 和 Setter 方法
	public BodyType getBodyType() {
		return bodyType;
	}

	public void setBodyType(BodyType newType) {
		if (this.bodyType != newType) {
			this.bodyType = newType;
		}
	}

	// 其他物理方法
	public void setVelocity(Vector2 vec2) {
		velocity.set(vec2);
	}
	public void setVelocity(float x, float y) {
		velocity.set(x, y);
	}
	public void addVelocity(Vector2 vec2) {
		addVelocity(vec2.x, vec2.y);
	}
	public void addVelocity(float x, float y) {
		velocity.add(x, y);
	}

	/**
	 * @return 一个速度副本, 要设置速度请使用setVelocity
	 */
	public Vector2 getVelocity() {
		return tmpVec2.set(velocity);
	}

	public void setPosition(float x, float y) {
		position.set(x, y);
	}

	public Vector2 getPosition() {
		return tmpVec2.set(position);
	}

	public void addPosition(Vector2 moved) {
		addPosition(moved.x, moved.y);
	}
	public void addPosition(float movedX, float movedY) {
		position.add(movedX, movedY);
	}

	public void setGravityScale(float gravityScale) {
		this.gravityScale = gravityScale;
	}

	public float getGravityScale() {
		return gravityScale;
	}

	public void attachCollider(ColliderComponent collider) {
		if (!attachedColliders.contains(collider)) {
			attachedColliders.add(collider);
		}
	}

	public void detachCollider(ColliderComponent collider) {
		attachedColliders.remove(collider);
	}

	public List<ColliderComponent> getAttachedColliders() {
		return attachedColliders;
	}

	@Override
	public void destroyImmediate() {
		super.destroyImmediate();
	}


	//静态工具方法===============================
//	public static boolean moveTo(GObject obj, float destinationX, float destinationY, float stepX, float stepY) {
//		RigidbodyComponent rigi = obj.getComponent(RigidbodyComponent.class);
//		float disX = destinationX - rigi.getPosition().x;
//		float disY = destinationY - rigi.getPosition().y;
//		float distance = (float) Math.sqrt(disX * disX + disY * disY);
//		float velX = Math.signum(disX) * Math.min(Math.abs(disX), Math.abs(stepX));
//		float velY = Math.signum(disY) * Math.min(Math.abs(disY), Math.abs(stepY));
//		float delta = 1/60f * 2;
//		rigi.getPosition().add(velX * delta, velY * delta);
//
//		boolean arrived = distance == 0;
////		Debug.info("MoveTo: (%s, %s), distance: %s", destinationX, destinationY, distance);
//		return arrived;
//	}

	public static boolean moveTo(GObject obj, float destinationX, float destinationY, float velocityX, float velocityY) {
		RigidbodyComponent rigi = obj.getComponent(RigidbodyComponent.class);
		float disX = destinationX - rigi.getPosition().x;
		float disY = destinationY - rigi.getPosition().y;
		float distance = (float) Math.sqrt(disX * disX + disY * disY);
		float velX = Math.signum(disX) * Math.abs(velocityX);
		float velY = Math.signum(disY) * Math.abs(velocityY);

		// 设置阈值，小于此距离视为抵达
		final float ARRIVAL_THRESHOLD = 0.5f;

		// 如果已经在阈值范围内，视为抵达
		if (distance <= ARRIVAL_THRESHOLD) {
			rigi.setVelocity(0, 0); // 停止移动
			return true;
		}

		// 设置匀速速度
		rigi.setVelocity(velX, velY);

		return false;
	}

	Vector2 tmpVec2 = new Vector2();
	public Vector2 getLastPosition() {
		return tmpVec2.set(lastPosition);
	}
	public void setLastPosition(Vector2 vec2) {
		setLastPosition(vec2.x, vec2.y);
	}
	public void setLastPosition(float  x, float y) {
		this.lastPosition.set(x, y);
	}
}
